home *** CD-ROM | disk | FTP | other *** search
/ Delphi Developer's Kit 1996 / Delphi Developer's Kit 1996.iso / power / sweep11 / swplogic / swplogic.c next >
Encoding:
C/C++ Source or Header  |  1995-12-22  |  17.8 KB  |  640 lines

  1. /* FILENAME: SWPLOGIC
  2.      PURPOSE : To Provide Generic logic for The Minesweeper game
  3.                          As provided with WIN 3.1                         */
  4. #include <values.h>
  5. #include "swplogic.h"
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <windowsx.h>
  9. #include <mem.h>
  10. #include <time.h>
  11. #include <stdlib.h>
  12. #include <assert.h>
  13. #define STRICT
  14. #define ASDLL
  15. #ifdef  ASDLL
  16.      #define MAXGAMEHANDLES 10
  17. #else
  18.      #define MAXGAMEHANDLES 1
  19. #endif
  20.  
  21. #define  MAXTIME    999
  22. char szDBG[128];
  23. typedef struct _gmElement_Tag
  24. {  SHOWNTYPE sideShown;   /* 0 = Top, 1 = Bottom */
  25.      PIECEVAL  Value    ;   /* 0..15 */
  26.    BOOL      Flagged; 
  27.    BOOL      WrongGuess;
  28. }GMELEMENT, *PGMELEMENT, FAR *LPGMELEMENT;
  29. LPGMELEMENT *pTest;
  30.  
  31.  
  32. typedef struct _game_Tag
  33. {
  34.    HSWP           hswp;
  35.    int           nRows;
  36.    int           nCols;
  37.    int            nMines;
  38.    HANDLE         hGame;
  39.    LPGMELEMENT   *lpElements;
  40.    HTASK          hOwnerTask;
  41.    GAMESTATE      gmState;
  42.      HWND           hTimerWnd;
  43.      WORD           seconds;
  44.      WORD           wCorrectGuesses;
  45.      WORD           wGuesses;
  46.    HWND           hListener;
  47. }GAME, *PGAME, FAR *LPGAME;
  48.  
  49. /* Local Declarations */
  50. GAME games[MAXGAMEHANDLES];
  51. void ShowAllUnFlaggedMines(LPGAME lpGamePtr);
  52. LOGICERR  PlayNeighbours(LPGAME lpGamePtr,int I,int J);
  53. BOOL FlagCountMatches(LPGAME lp,int I,int J, int *);
  54. BOOL CheckFlagPositions(LPGAME lp,int I,int J);
  55. int RemoveGame(HSWP hswp);
  56. void  ShowAllContiguousBlanks(LPGAME lpGamePtr,int I,int J,HWND hwnd);
  57. HSWP AddGame(int nRows, int nCols, int nMines,
  58.                          HWND hTimer,HTASK hOwner,LOGICERR *le);
  59. int InitGames(void);
  60. BOOL RandomizeGame(LPGAME lpGame);
  61. LPGAME GetGame(HSWP hswp);
  62. PIECEVAL CountNeighbors(LPGMELEMENT pGame[], int i,int j,int rowMax,int ColMax );
  63. int INBOUNDS(int row,int col,int rowMax,int colMax);
  64.  
  65. HSWP FAR PASCAL _export logInitGame (int Rows,
  66.                                                                          int Cols,
  67.                                                                          int Mines,
  68.                                                                          HWND hwndTimer,
  69.                                                                          LOGICERR *logErr)
  70. {  int i;
  71.    HSWP hRetVal = NULL;
  72.  
  73.      if (Mines > Rows*Cols)
  74.          *logErr = GMERR_TOOMANYMINES;
  75.      else
  76.    if (!IsWindow(hwndTimer))
  77.          *logErr = GMERR_INVALIDHWND;
  78.    else
  79.         hRetVal =  AddGame(Rows,Cols,Mines,hwndTimer,GetCurrentTask(),logErr);
  80.    return hRetVal;
  81. }
  82.  
  83.  
  84. PIECEVAL FAR PASCAL _export logGetSideShown(HSWP hswp, int I, int J)
  85. {
  86.     PIECEVAL pv;
  87.     LPGAME lpGamePtr = NULL;
  88.     lpGamePtr = GetGame(hswp);
  89.     if (lpGamePtr == NULL)
  90.         pv = PV_BADGAMEHANDLE;
  91.     else{
  92.         if (!INBOUNDS(I,J,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  93.              pv = INVALID_PIECE;
  94.         else{ 
  95.        if ( (lpGamePtr->lpElements[I][J].sideShown ==TOP) &&
  96.                         (!lpGamePtr->lpElements[I][J].Flagged)        ) {
  97.                  if (lpGamePtr->gmState != PLAYING && lpGamePtr->gmState != WAITING_AFTERRESET)
  98.                      return UP;
  99.                  else
  100.                      return NONE;
  101.              }
  102.              else
  103.  
  104.                      if(lpGamePtr->lpElements[I][J].Flagged )
  105.                         return (UPFLAG);
  106.                      else
  107.                         return lpGamePtr->lpElements[I][J].Value;
  108.         }
  109.     }
  110.     return pv;
  111. }
  112.  
  113.  
  114. LOGICERR FAR PASCAL logSetFlag(HSWP hswp, int I, int J)
  115. {
  116.   LOGICERR le;
  117.     LPGAME lpGamePtr = NULL;
  118.     lpGamePtr = GetGame(hswp);
  119.     if (lpGamePtr == NULL)
  120.         le = GMERR_BADGAMEHANDLE;
  121.     else
  122.     {
  123.         if (!INBOUNDS(I,J,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  124.              le = GMERR_INDEXOUTOFRANGE;
  125.         else
  126.         {
  127.              if (lpGamePtr->gmState != PLAYING &&
  128.                      lpGamePtr->gmState != WAITING_AFTERRESET)
  129.                     le = UNKNOWN;
  130.        else
  131.                 if (lpGamePtr->lpElements[I][J].sideShown == TOP)    {
  132.                     if (lpGamePtr->lpElements[I][J].Flagged) {
  133.                         lpGamePtr->wGuesses -= 1;
  134.                         lpGamePtr->lpElements[I][J].Flagged = FALSE;
  135.                         if (lpGamePtr->lpElements[I][J].Value == MINE)
  136.                             lpGamePtr->wCorrectGuesses -= 1;
  137.                         
  138.           }else{
  139.                         lpGamePtr->wGuesses += 1;
  140.                         lpGamePtr->lpElements[I][J].Flagged = TRUE;
  141.                         if (lpGamePtr->lpElements[I][J].Value == MINE)
  142.                             lpGamePtr->wCorrectGuesses += 1;
  143.            }
  144.                     le = GM_OK;
  145.                 }
  146.                 if (lpGamePtr->wCorrectGuesses == lpGamePtr->nMines)
  147.                     lpGamePtr->gmState  =  WON;
  148.         } 
  149.     }
  150.     return le;
  151. }
  152.  
  153. WORD FAR PASCAL _export logGetMineCount(HSWP hswp)
  154. {
  155.    LPGAME  lpGamePtr = GetGame(hswp);
  156.      if (lpGamePtr != NULL)
  157.      {
  158.          return (lpGamePtr->nMines - lpGamePtr->wGuesses);
  159.    }
  160.    else
  161.      return MAXINT;
  162. }
  163.  
  164. LOGICERR    FAR PASCAL _export logPlay(HSWP hswp,    int I, int J, BOOL isShifted)
  165. { int numFlags;
  166.   int row,col;
  167.   LPGAME lpGamePtr = NULL;
  168.     LPGMELEMENT *lppGmElements;
  169.  
  170.     lpGamePtr = GetGame(hswp);
  171.     if (!INBOUNDS(I,J,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  172.         return -2;
  173.  
  174.     if (lpGamePtr == NULL)
  175.         return GMERR_BADGAMEHANDLE;
  176.  
  177.     if((lpGamePtr->gmState != PLAYING) &&
  178.          (lpGamePtr->gmState != WAITING_AFTERRESET))
  179.     return GMERR_UNKNOWN;
  180.  
  181.     lppGmElements = lpGamePtr->lpElements;
  182.     if (lppGmElements == NULL)
  183.         return GMERR_MEMFAILURE;
  184.  
  185.   if ((lpGamePtr->gmState != WAITING_AFTERRESET )&&
  186.             (lpGamePtr->gmState != PLAYING)            &&
  187.             (lpGamePtr->gmState != UNKNOWN)              )
  188.         return GMERR_UNKNOWN;
  189.  
  190.     if ( !INBOUNDS(I,J,lpGamePtr->nRows-1,lpGamePtr->nCols-1 ))
  191.         return GMERR_INDEXOUTOFRANGE;
  192.  
  193.   if (lpGamePtr->gmState == WAITING_AFTERRESET ||
  194.             lpGamePtr->gmState == UNKNOWN              )
  195.        lpGamePtr->gmState = PLAYING;
  196.  
  197.     if (isShifted)
  198.     {
  199.         if (FlagCountMatches(lpGamePtr,I,J,&numFlags))
  200.         {
  201.       OutputDebugString("FlagCountMatches\n");
  202.             if (numFlags != 0)
  203.                 if (CheckFlagPositions(lpGamePtr,I,J)){
  204.                     return PlayNeighbours(lpGamePtr,I,J);
  205.         }
  206.                 else{
  207.                      lpGamePtr->gmState = LOST;
  208.            ShowAllUnFlaggedMines(lpGamePtr);
  209.                return GMERR_LOST;
  210.         }
  211.     }
  212.         else{
  213.             OutputDebugString("FlagCount Did Not Match\n");
  214.             return -45;
  215.     }
  216.     }
  217.     if ( (lppGmElements[I][J].sideShown != TOP )||
  218.              (lppGmElements[I][J].Flagged          ))
  219.         return GMERR_PIECEALREADYPLAYED;
  220.  
  221.     lppGmElements[I][J].sideShown = BOTTOM;
  222.  
  223.     if (lppGmElements[I][J].Value == MINE)    {
  224.          /* Change this so that value is never changed */
  225.          //lppGmElements[I][J].Value = WRONGGUESS;
  226.          lppGmElements[I][J].WrongGuess = TRUE;
  227.          lpGamePtr->gmState = LOST;
  228.      ShowAllUnFlaggedMines(lpGamePtr);
  229.          return GMERR_LOST;
  230.     }
  231.  
  232.     for (row = I-1; row <= I + 1; row++)
  233.         for (col = J - 1; col <= J+1; col++)
  234.             if (INBOUNDS(row,col,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  235.                 if (lppGmElements[row][col].sideShown == BOTTOM)
  236.                     if (CountNeighbors(lppGmElements,row,col,lpGamePtr->nRows-1,
  237.                                                             lpGamePtr->nCols-1) == NONE){
  238.                          ShowAllContiguousBlanks(lpGamePtr, row,col,lpGamePtr->hTimerWnd);
  239.                          return  GM_MORETOPLAY ;
  240.                     }
  241.  return GM_OK;
  242. }
  243.  
  244. void  ShowAllContiguousBlanks(LPGAME lpGamePtr,int I,int J,HWND hwnd)
  245. {
  246.    int row,col;
  247.         for (row = I-1; row <= I + 1; row++)
  248.          for (col = J - 1; col <= J+1; col++)
  249.             if (INBOUNDS(row,col,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  250.                 if ((lpGamePtr->lpElements[row][col].sideShown == TOP) &&
  251.                         (lpGamePtr->lpElements[row][col].Value  != MINE))        {
  252.  
  253.                             lpGamePtr->lpElements[row][col].sideShown = BOTTOM;
  254.                             SendMessage(lpGamePtr->hTimerWnd,WM_BLANKCELL,0,MAKELONG(row,col));
  255.                             if (lpGamePtr->lpElements[row][col].Value  == NONE)
  256.                             ShowAllContiguousBlanks(lpGamePtr, row,col, hwnd);
  257.         }
  258. }
  259.  
  260. LOGICERR  PlayNeighbours(LPGAME lp,int I,int J)
  261. {
  262.      int row,col;
  263.      LOGICERR retVal = GM_OK;
  264.      if (INBOUNDS(I,J,lp->nRows-1,lp->nCols-1))
  265.          for (row = I - 1; row <= I + 1; row++)
  266.             for (col = J - 1; col <= J + 1; col++)
  267.             if (!((row == I) && (col == J)))
  268.                     if (INBOUNDS(row,col,lp->nRows-1,lp->nCols-1))
  269.                         if (lp->lpElements[row][col].Flagged) {
  270.                              if (lp->lpElements[row][col].Value != MINE)
  271.                {
  272.                                     lp->lpElements[row][col].WrongGuess = TRUE;
  273.                                     return GMERR_LOST;
  274.                }
  275.                
  276.                         }else
  277.                         if (lp->lpElements[row][col].sideShown == TOP){
  278.                             if (lp->lpElements[row][col].Value == MINE)    {
  279.                                  lp->lpElements[row][col].WrongGuess = TRUE;
  280.                                  return GMERR_LOST;
  281.                             }
  282.                             else
  283.                             if (lp->lpElements[row][col].Value == NONE)
  284.                                 ShowAllContiguousBlanks(lp, row,col,lp->hTimerWnd);
  285.                             else
  286.                                 lp->lpElements[row][col].sideShown = BOTTOM;
  287.                          
  288.             }
  289.     return retVal;
  290. }
  291.  
  292. void ShowAllUnFlaggedMines(LPGAME lpGamePtr)
  293. {
  294.    
  295.    int i, j;
  296.      if (lpGamePtr != NULL){
  297.             for (i = 0; i < lpGamePtr->nRows; i++)
  298.                 for (j = 0; j < lpGamePtr->nCols; j++)
  299.                     if ((lpGamePtr->lpElements[i][j].Value     == MINE)    &&
  300.                             (lpGamePtr->lpElements[i][j].sideShown == TOP )    &&
  301.                           (!lpGamePtr->lpElements[i][j].Flagged         )){
  302.                          lpGamePtr->lpElements[i][j].sideShown = BOTTOM;
  303.                          PostMessage(lpGamePtr->hTimerWnd,WM_BLANKCELL,0,MAKELONG(i,j));
  304.                     }else
  305.                     if((lpGamePtr->lpElements[i][j].Value != MINE)          &&
  306.                             (lpGamePtr->lpElements[i][j].Flagged            )      )   {
  307.                          lpGamePtr->lpElements[i][j].sideShown = BOTTOM;
  308.                          lpGamePtr->lpElements[i][j].Value  = ANOTHERWRONGGUESS;
  309.                          PostMessage(lpGamePtr->hTimerWnd,WM_BLANKCELL,0,MAKELONG(i,j));
  310.                     }
  311.    }
  312. }
  313.  
  314. PIECEVAL    FAR PASCAL _export logGetValue(HSWP hswp, int I, int J)
  315. {
  316.   PIECEVAL retPIECE;
  317.   LPGMELEMENT *lppGmElements;
  318.     LPGAME lpGamePtr = GetGame(hswp);
  319.     if (lpGamePtr == NULL)
  320.         return PV_BADGAMEHANDLE;
  321.     if (lpGamePtr->lpElements == NULL)
  322.         return PV_MEMFAILURE;
  323.     lppGmElements = lpGamePtr->lpElements;
  324.     if (!INBOUNDS(I,J,lpGamePtr->nRows-1,lpGamePtr->nCols-1))
  325.         retPIECE =  INVALID_PIECE;
  326.     else
  327.     if (lppGmElements[I][J].sideShown == TOP)
  328.     {
  329.         if (lppGmElements[I][J].Flagged)
  330.             retPIECE = UPFLAG;
  331.         else
  332.          retPIECE = TOP;
  333.     }else // This means we are returning the bottom value
  334.   {
  335.         if (lppGmElements[I][J].WrongGuess)
  336.             retPIECE = WRONGGUESS;
  337.     else
  338.           retPIECE = lppGmElements[I][J].Value;
  339.   }
  340.   return retPIECE;
  341. }
  342.  
  343. GAMESTATE    FAR PASCAL _export logGetGameState(HSWP hswp)
  344. {
  345.   LPGAME lpGamePtr;
  346.      lpGamePtr = GetGame(hswp) ;
  347.   if (lpGamePtr != NULL)
  348.      return  lpGamePtr->gmState;    
  349.     else
  350.         return UNKNOWN;
  351. }
  352.  
  353. LOGICERR    FAR PASCAL _export logFreeGame(HSWP hswp)
  354. {
  355.     if (GetGame(hswp) != NULL){
  356.         if (RemoveGame(hswp))
  357.             return GM_OK;
  358.         else
  359.             return GMERR_BADGAMEHANDLE;
  360.     }else
  361.         return GMERR_BADGAMEHANDLE;
  362. }
  363.  
  364. LOGICERR  FAR PASCAL _export logIncrementGameTime(HSWP hswp)
  365. {
  366.    LOGICERR le;
  367.      LPGAME lpGamePtr;
  368.      lpGamePtr = GetGame(hswp) ;
  369.    le = UNKNOWN;
  370.      if (lpGamePtr == NULL)
  371.          le = GMERR_BADGAMEHANDLE;
  372.      else {
  373.          if (lpGamePtr->seconds <= MAXTIME) {
  374.                 PostMessage(lpGamePtr->hTimerWnd,WM_SWEEPTIMER,lpGamePtr->seconds++,0L);
  375.                 le = GM_OK;
  376.      }
  377.          else     {
  378.         lpGamePtr->gmState = TIMEDOUT; 
  379.         le = GMERR_TIMEDOUT;
  380.          }
  381.    }
  382.   return le;
  383. }
  384.  
  385. #ifdef ASDLL
  386. #pragma argsused;
  387. int FAR PASCAL LibMain (HINSTANCE hInstance,
  388.                                                  WORD wDataSeg,
  389.                                                     WORD cbHeapSize,
  390.                                                  LPSTR lpCmdLine)
  391. {
  392.    InitGames();
  393.      return 1;
  394. }
  395. #pragma argsused
  396. int FAR PASCAL WEP (int nParameter)
  397. {
  398.    int i;
  399.      for (i = 0; i < MAXGAMEHANDLES; i++)
  400.       RemoveGame(games[i].hswp);
  401.    return 1;
  402. }
  403. #endif
  404. int
  405. RemoveGame(HSWP hswp)
  406. {
  407.   LPGAME lpGamePtr;
  408.     int retVal = -1;
  409.     int j = 0;
  410.     if (hswp == NULL)
  411.         return 0;
  412.  
  413.   lpGamePtr = GetGame(hswp);
  414.     if (lpGamePtr!=NULL)    {
  415.             for ( j = 0;  j < lpGamePtr->nRows; j++)
  416.                 GlobalFreePtr(lpGamePtr->lpElements[j]);
  417.  
  418.             GlobalFreePtr(lpGamePtr->lpElements);
  419.             lpGamePtr->hGame = NULL;
  420.             lpGamePtr->nRows     = 0;
  421.             lpGamePtr->nCols     = 0;
  422.             lpGamePtr->hswp      = NULL;
  423.             lpGamePtr->gmState   = UNKNOWN;
  424.             lpGamePtr->nMines    = 0;
  425.             lpGamePtr->hTimerWnd = NULL;
  426.             lpGamePtr->hOwnerTask= NULL;
  427.       lpGamePtr->seconds = 0;
  428.             retVal = 1;
  429.     }
  430.     return retVal;
  431. }
  432.  
  433.  
  434. HSWP
  435. AddGame(int nRows,  int nCols,   int nMines,
  436.                 HWND hTimerTo,HTASK hOwner,LOGICERR *le)
  437. {
  438.    int j, k;
  439.      int i = 0;
  440.      *le = GM_OK;
  441.      while ((i <  MAXGAMEHANDLES ) && (games[i].hswp != NULL))
  442.      ++i;
  443.  
  444.      if (i == MAXGAMEHANDLES) {
  445.          *le = GMERR_TOOMANYGAMES;
  446.             return NULL;
  447.    }
  448.      games[i].lpElements = (LPGMELEMENT*)GlobalAllocPtr(GMEM_SHARE|GMEM_ZEROINIT,
  449.                                                                     (DWORD)sizeof(LPGMELEMENT)*nRows);
  450.      if (games[i].lpElements == NULL) {
  451.             *le = GMERR_MEMFAILURE;
  452.        return NULL;
  453.      }
  454.      for (j = 0 ; j < nRows; j++) {
  455.          games[i].lpElements[j] = (LPGMELEMENT)GlobalAllocPtr(GMEM_SHARE  |
  456.                                                               GMEM_ZEROINIT,
  457.                                                                            (DWORD)sizeof(GMELEMENT)*nCols);
  458.          if (games[i].lpElements[j] == NULL)  {
  459.            assert(games[i].lpElements[j] != NULL);
  460.            for (k = 0; k < j; k++)
  461.                GlobalFreePtr(games[i].lpElements[k]);
  462.              GlobalFreePtr(games[i].lpElements);
  463.              *le = GMERR_MEMFAILURE;
  464.              return NULL;
  465.      }
  466.      }
  467.       games[i].hGame                     =(HANDLE)GlobalHandle(HIWORD(games[i].lpElements));
  468.       games[i].nRows                     = nRows;
  469.       games[i].nCols                     = nCols;
  470.       games[i].hswp                      = games[i].hGame;
  471.       games[i].gmState                   = WAITING_AFTERRESET;
  472.     games[i].nMines                    = nMines;
  473.     games[i].hTimerWnd                 = hTimerTo;
  474.       games[i].hOwnerTask                = hOwner;
  475.       games[i].seconds                   = 0;
  476.         games[i].wCorrectGuesses     = 0;
  477.  
  478.         games[i].wGuesses                 = 0;
  479.     games[i].hListener                 = NULL;
  480.       if (!RandomizeGame(&games[i])) {
  481.        *le = GMERR_UNKNOWN;
  482.             RemoveGame(games[i].hswp);
  483.       return NULL;
  484.         }
  485.     return games[i].hswp;
  486. }
  487.  
  488.  
  489. int
  490. InitGames(void)
  491. {
  492.    int i;
  493.      for (i = 0; i < MAXGAMEHANDLES; i++)
  494.          games[i].hswp = NULL;
  495.    return GM_OK;
  496. }
  497.  
  498. BOOL
  499. RandomizeGame(LPGAME lpGamePtr)
  500. {
  501.      BOOL retVal = FALSE;
  502.      time_t t;
  503.    int row,col;
  504.      int mineCount = 0;
  505.      if (lpGamePtr != NULL) {
  506.          if (lpGamePtr->lpElements != NULL) {
  507.         retVal = TRUE;
  508.        /* Initialize the grid to having the Topside shown */
  509.              /* Now Set the Values to NONE */
  510.              for (row = 0; row < lpGamePtr->nRows; row++)
  511.                     for (col = 0; col < lpGamePtr->nCols; col++)      {
  512.                          lpGamePtr->lpElements[row][col].WrongGuess = FALSE;
  513.                          lpGamePtr->lpElements[row][col].Flagged    = FALSE;
  514.                          lpGamePtr->lpElements[row][col].Value      = NONE;
  515.                          lpGamePtr->lpElements[row][col].sideShown   = TOP;
  516.           }
  517.              /* Throw Mines down in random positions  */
  518.              /* Increment the Minecount only if the   */
  519.              /* position that is in question has not  */
  520.              /* been filled by a previous trip through*/
  521.              /* the Loop                              */
  522.              srand((unsigned) time(&t));
  523.              while (mineCount < lpGamePtr->nMines){
  524.                  row = rand()%lpGamePtr->nRows;
  525.                  col = rand()%lpGamePtr->nCols;
  526.                  if (lpGamePtr->lpElements[row][col].Value != MINE)     {
  527.                         mineCount++;
  528.                         lpGamePtr->lpElements[row][col].Value = MINE;
  529.          }
  530.              }
  531.              /* Now Set the Neighbor mines for each field */
  532.              for (row = 0; row < lpGamePtr->nRows; row++)
  533.                     for (col = 0; col < lpGamePtr->nCols; col++)
  534.                          if (lpGamePtr->lpElements[row][col].Value != MINE)
  535.                                 lpGamePtr->lpElements[row][col].Value =
  536.                   CountNeighbors(lpGamePtr->lpElements,
  537.                                                   row,col,
  538.                                                                     lpGamePtr->nRows - 1,
  539.                                                                     lpGamePtr->nCols - 1);
  540.          }
  541.      } 
  542.    return retVal;
  543. }
  544.  
  545. LPGAME
  546. GetGame(HSWP hswp)
  547. {
  548.   int i;
  549.     for (i = 0; i < MAXGAMEHANDLES; i++)
  550.          if (games[i].hswp == hswp) 
  551.              return (&games[i]);
  552.  
  553.   return (LPGAME)NULL;
  554. }
  555.  
  556. PIECEVAL CountNeighbors(LPGMELEMENT pGame[],
  557.                                                 int i,        int j,
  558.                                                 int rowMax,int colMax )
  559. {
  560.      PIECEVAL pV= NONE;
  561.      int row,col;
  562.      int nNeighborMineCount = 0;
  563.  
  564.      for (row = i - 1; row <= i + 1; row++)
  565.          for (col = j - 1; col <= j + 1; col ++)
  566.              if ((row == i)&&(col == j))
  567.                  continue;
  568.        else
  569.                  if (INBOUNDS(row,col,rowMax,colMax) )
  570.                     if (pGame[row][col].Value == MINE)
  571.                         nNeighborMineCount++;
  572.  
  573.      switch (nNeighborMineCount)     {
  574.             case 0: pV = NONE ;break;
  575.             case 1: pV = ONE    ;break;
  576.             case 2: pV = TWO  ;break;
  577.             case 3: pV = THREE;break;
  578.             case 4: pV = FOUR ;break; 
  579.             case 5: pV = FIVE ;break;
  580.             case 6: pV = SIX  ;break;
  581.             case 7: pV = SEVEN;break;
  582.             case 8: pV = EIGHT;break;
  583.             default:  assert(pV != 0);
  584.      }
  585.    return pV;
  586. }
  587.  
  588. BOOL FlagCountMatches(LPGAME lp,int I,int J,int *nFlags)
  589. {
  590.     int row,col;
  591.   int flagCount = 0;
  592.     BOOL retVal = FALSE;
  593.     if (INBOUNDS(I,J,lp->nRows-1,lp->nCols-1))
  594.         for (row = I - 1; row <= I + 1; row++)
  595.             for (col = J - 1; col <= J + 1; col++)
  596.             if (!((row == I) && (col == J)))
  597.                   if (INBOUNDS(row,col,lp->nRows-1,lp->nCols-1))
  598.                         if (lp->lpElements[row][col].Flagged)
  599.                             ++flagCount;
  600.  
  601.         *nFlags = flagCount;
  602.     
  603.       switch (flagCount){
  604.             case 0: if (lp->lpElements[I][J].Value == NONE )    retVal = TRUE;break;
  605.             case 1: if (lp->lpElements[I][J].Value == ONE  )    retVal = TRUE;break;
  606.             case 2: if (lp->lpElements[I][J].Value == TWO  )  retVal = TRUE;break;
  607.             case 3: if (lp->lpElements[I][J].Value == THREE)     retVal = TRUE;break;
  608.             case 4: if (lp->lpElements[I][J].Value == FOUR )    retVal = TRUE;break;
  609.             case 5: if (lp->lpElements[I][J].Value == FIVE )    retVal = TRUE;break;
  610.             case 6: if (lp->lpElements[I][J].Value == SIX  )    retVal = TRUE;break;
  611.             case 7: if (lp->lpElements[I][J].Value == SEVEN)  retVal = TRUE;break;
  612.             case 8: if (lp->lpElements[I][J].Value == EIGHT)  retVal = TRUE;break;
  613.          }
  614.      sprintf(szDBG,"The flagcount = %d RetVal = %d\n",flagCount,retVal);
  615.    OutputDebugString(szDBG);
  616.    return retVal;
  617. }
  618.  
  619. BOOL CheckFlagPositions(LPGAME lp,int I,int J)
  620. {
  621.   int row,col;
  622.     if (INBOUNDS(I,J,lp->nRows-1,lp->nCols-1))
  623.         for (row = I - 1; row <= I + 1; row++)
  624.             for (col = J - 1; col <= J + 1; col++)
  625.             if (!((row == I) && (col == J)))
  626.                   if (INBOUNDS(row,col,lp->nRows-1,lp->nCols-1))
  627.                         if (lp->lpElements[row][col].Flagged)
  628.                             if(lp->lpElements[row][col].Value != MINE)
  629.                 return FALSE;
  630.    return TRUE;
  631. }
  632.  
  633. int INBOUNDS(int row,int col,int rowMax,int colMax)
  634. {
  635.   if ((row > rowMax) || (col > colMax) ||
  636.             (row < 0     ) || (col < 0     )   )
  637.         return 0;
  638.     else
  639.     return 1;
  640. }